package com.xxl.job.admin.core.client;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.xxl.job.admin.core.util.JacksonUtil;
import com.xxl.job.core.context.XxlJobContext;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import org.springframework.stereotype.Component;
import org.springframework.util.Base64Utils;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;

/**
 * @Description: http请求处理器
 * @Author: zhanglu
 * @Date: 2022/8/29 11:37
 */
@Component
public class HttpRequestHanlder {

  /**
   * 4、跨平台Http任务
   *  参数示例：
   *      "url: http://www.baidu.com\n" +
   *      "method: get\n" +
   *      "data: content\n";
   */
  @XxlJob("httpJobHandler")
  public void httpJobHandler() throws Exception {

    // param parse
    String param = XxlJobHelper.getJobParam();
    if (param==null || param.trim().length()==0) {
      XxlJobHelper.log("param["+ param +"] invalid.");

      XxlJobHelper.handleFail();
      return;
    }

    String[] httpParams = param.split("\n");
    String url = null;
    String method = null;
    String data = null;
    for (String httpParam: httpParams) {
      if (httpParam.startsWith("url:")) {
        url = httpParam.substring(httpParam.indexOf("url:") + 4).trim();
      }
      if (httpParam.startsWith("method:")) {
        method = httpParam.substring(httpParam.indexOf("method:") + 7).trim().toUpperCase();
      }
      if (httpParam.startsWith("data:")) {
        data = httpParam.substring(httpParam.indexOf("data:") + 5).trim();
      }
    }

    // param valid
    if (url==null || url.trim().length()==0) {
      XxlJobHelper.log("url["+ url +"] invalid.");

      XxlJobHelper.handleFail();
      return;
    }
    if (method==null || !Arrays.asList("GET", "POST").contains(method)) {
      XxlJobHelper.log("method["+ method +"] invalid.");

      XxlJobHelper.handleFail();
      return;
    }
    boolean isPostMethod = method.equals("POST");

    // request
    HttpURLConnection connection = null;
    BufferedReader bufferedReader = null;
    try {
      //url后面拼接logId，同步请求响应太慢，可以等真正处理完再回调过来，
      XxlJobHttpLogDo httpLogDo = new XxlJobHttpLogDo().setLodId(XxlJobContext.getXxlJobContext().getTriggerParam().getLogId())
              .setJobLogFileName(XxlJobContext.getXxlJobContext().getJobLogFileName());
      String xxljoblogdata = JacksonUtil.writeValueAsString(httpLogDo);
      xxljoblogdata = Base64Utils.encodeToString(xxljoblogdata.getBytes(StandardCharsets.UTF_8));
      url += "?xxljoblogdata=" + xxljoblogdata;
      // connection
      URL realUrl = new URL(url);
      connection = (HttpURLConnection) realUrl.openConnection();

      int executorTimeout = XxlJobContext.getXxlJobContext().getTriggerParam().getExecutorTimeout();
      executorTimeout = executorTimeout == 0 ? 10 : executorTimeout;

      // connection setting
      connection.setRequestMethod(method);
      connection.setDoOutput(isPostMethod);
      connection.setDoInput(true);
      connection.setUseCaches(false);
      connection.setReadTimeout(executorTimeout * 1000);
      connection.setConnectTimeout(3 * 1000);
      connection.setRequestProperty("connection", "Keep-Alive");
      connection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
      connection.setRequestProperty("Accept-Charset", "application/json;charset=UTF-8");
      connection.setRequestProperty("access_token", "hxfl-xxl-job-admin");

      // do connection
      connection.connect();

      // data
      if (isPostMethod && data!=null && data.trim().length()>0) {
        DataOutputStream dataOutputStream = new DataOutputStream(connection.getOutputStream());
        dataOutputStream.write(data.getBytes("UTF-8"));
        dataOutputStream.flush();
        dataOutputStream.close();
      }

      // valid StatusCode
      int statusCode = connection.getResponseCode();
      if (statusCode != 200) {
        throw new RuntimeException("Http Request StatusCode(" + statusCode + ") Invalid.");
      }

      // result
      bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
      StringBuilder result = new StringBuilder();
      String line;
      while ((line = bufferedReader.readLine()) != null) {
        result.append(line);
      }
      String responseMsg = result.toString();

      XxlJobHelper.log(responseMsg);

      return;
    } catch (Exception e) {
      XxlJobHelper.log(e);

      XxlJobHelper.handleFail();
      return;
    } finally {
      try {
        if (bufferedReader != null) {
          bufferedReader.close();
        }
        if (connection != null) {
          connection.disconnect();
        }
      } catch (Exception e2) {
        XxlJobHelper.log(e2);
      }
    }

  }


}
